home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <libc.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <pwd.h>
- #include "VCal.h"
- #include "Utils.h"
- #include "DayView.h"
- #include "MonthOverview.h"
- #include "WeekOverview.h"
- #include "Info.h"
- #include "Preferences.h"
- #include "PrefDialog.h"
- #include "PrintPS.h"
- #include "path.h"
- #include <Vk/VkFormat.h>
- #include <Vk/VkHelp.h>
- #include <Vk/VkHelpPane.h>
- #include <Vk/VkFileSelectionDialog.h>
- #include <Vk/VkResource.h>
- #include <Vk/VkRepeatButton.h>
- #include <Vk/VkPopupMenu.h>
- #include <Vk/VkSubMenu.h>
- #include <Vk/VkSimpleWindow.h>
- #include <Vk/VkMenuBar.h>
- #include <Vk/VkHelpPane.h>
- #include <Vk/VkWarningDialog.h>
- #include <Vk/VkQuestionDialog.h>
- #include <Vk/VkFatalErrorDialog.h>
- #include <Vk/VkChildrenHandler.h>
- #include <Vk/VkPrefItem.h>
-
- #include <Xm/Form.h>
- #include <Xm/RowColumn.h>
- #include <Xm/PushB.h>
- #include <Xm/PushBG.h>
- #include <Xm/Label.h>
- #include <Xm/LabelG.h>
- #include <Xm/SeparatoG.h>
- #include <Xm/MessageB.h>
- #include <Xm/FileSB.h>
-
- static Arg args[10];
- static int count;
-
- #define TILE_DISTANCE 5
-
- void
- VCal::load_menu(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->loadMenu();
- }
-
- void
- VCal::save_menu(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->writeFile();
- }
-
- Boolean
- VCal::write_file(XtPointer client_data)
- {
- VCal *obj = (VCal *) client_data;
-
- XmUpdateDisplay(obj->baseWidget());
- obj->writeFile();
- obj->writeID = NULL;
- return True;
- }
-
- void
- VCal::saveas_menu(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->saveAsMenu();
- }
-
- void
- VCal::save_text(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- if (obj->dayText && obj->dayText->getValue()) {
- obj->saveAsTextMenu(False, obj, obj->nowDay, obj->nowMonth, obj->nowYear);
- } else {
- obj->saveAsTextMenu(False, obj, obj->nowDay, obj->month, obj->year);
- }
- }
-
- void
- VCal::display_overview(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->displayMonthOverview();
- }
-
- void
- VCal::week_overview(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->displayWeekOverview();
- }
-
- void
- VCal::month_print(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->monthPrint();
- }
-
- void
- VCal::savetext_ok(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->saveAsTextOK();
- obj->saveAsTextCancel();
- }
-
- void
- VCal::savetext_cancel(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->saveAsTextCancel();
- }
-
- void
- VCal::pref_menu(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->prefMenu();
- }
-
- void
- VCal::factory_menu(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->factoryMenu();
- }
-
- void
- VCal::quit_menu(Widget, XtPointer, XtPointer)
- {
- theApplication->quitYourself();
- }
-
- void
- VCal::save_quit(Widget, XtPointer client_data, XtPointer)
- {
- VCal *obj = (VCal *) client_data;
-
- if (obj->writeFile()) {
- delete obj;
- }
- }
-
- void
- VCal::timeout_proc(XtPointer client_data, XtIntervalId *)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->handleTimeOut();
- }
-
- void
- VCal::snooze_proc(XtPointer client_data, XtIntervalId *id)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->handleSnooze(*id);
- }
-
- void
- VCal::month_select(Widget w, XtPointer client_data, XEvent *event)
- {
- VCal *obj = (VCal *) client_data;
-
- if (event->xbutton.button == 1 && w == obj->monthHeader) {
- obj->displayToday();
- } else if (event->xbutton.button == 3) {
- obj->displayActionsPopup(&event->xbutton);
- }
- }
-
- void
- VCal::day_select(Widget w, XtPointer client_data, XtPointer call_data)
- {
- VCal *obj = (VCal *) client_data;
- XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *) call_data;
- int day;
-
- count = 0;
- XtSetArg(args[count], XmNuserData, &day); count++;
- XtGetValues(w, args, count);
- if (cb->event && cb->event->type == ButtonRelease &&
- (cb->event->xbutton.state & ShiftMask)) {
- obj->weekSelect(day);
- } else {
- obj->daySelect(day);
- }
- }
-
- void
- VCal::month_popup(Widget, XtPointer client_data, XtPointer)
- {
- VkCallbackStruct *cb = (VkCallbackStruct *) client_data;
- VCal *obj = (VCal *) cb->obj;
- int month = (int) cb->client_data;
-
- obj->selectMonth(month);
- }
-
- void
- VCal::resize_day(Widget, XtPointer client_data, XEvent *event, Boolean *)
- {
- VCal *obj = (VCal *) client_data;
-
- if (event->type == ConfigureNotify) {
- obj->resizeDay();
- }
- }
-
- Boolean
- VCal::check_file(XtPointer client_data)
- {
- VCal *obj = (VCal *) client_data;
-
- obj->checkFileStat();
- return True;
- }
-
- Boolean
- VCal::dialog_delete(XtPointer client_data)
- {
- VkQuestionDialog *dialog = (VkQuestionDialog *) client_data;
-
- delete dialog;
- return True;
- }
-
- void
- VCal::alarm_dismiss(Widget, XtPointer client_data, XtPointer)
- {
- EntryAlarmInfo *info = (EntryAlarmInfo *) client_data;
- VCal *obj = (VCal *) info->data;
-
- obj->alarmDismiss(info);
- }
-
- void
- VCal::alarm_delete(Widget, XtPointer client_data, XtPointer)
- {
- EntryAlarmInfo *info = (EntryAlarmInfo *) client_data;
- VCal *obj = (VCal *) info->data;
-
- obj->alarmDelete(info);
- }
-
- void
- VCal::alarm_snooze(Widget, XtPointer client_data, XtPointer)
- {
- EntryAlarmInfo *info = (EntryAlarmInfo *) client_data;
- VCal *obj = (VCal *) info->data;
-
- obj->alarmSnooze(info);
- }
-
- /**********************************************************************/
-
- void VCal::afterRealizeHook()
- {
- int x;
- GC tempGC;
-
- tile = XCreatePixmap(XtDisplay(_baseWidget),
- XtWindow(_baseWidget),
- TILE_DISTANCE, TILE_DISTANCE, 1);
- tempGC = XCreateGC(XtDisplay(_baseWidget), tile, 0, NULL);
- XSetForeground(XtDisplay(_baseWidget), tempGC, 0);
- XFillRectangle(XtDisplay(_baseWidget), tile, tempGC, 0, 0,
- TILE_DISTANCE, TILE_DISTANCE);
- XSetForeground(XtDisplay(_baseWidget), tempGC, 1);
- XDrawPoint(XtDisplay(_baseWidget), tile, tempGC, 0, 0);
- for (x=1; x<TILE_DISTANCE; x++) {
- XDrawPoint(XtDisplay(_baseWidget), tile, tempGC, x, TILE_DISTANCE-x);
- }
- XFreeGC(XtDisplay(_baseWidget), tempGC);
-
- XRaiseWindow(XtDisplay(clockLabel), XtWindow(clockLabel));
- resizeDay();
- }
-
- void
- VCal::deleteDayView(DayView *obj)
- {
- if (obj && obj == dayView) {
- dayView->hide();
- if (weekOverview) {
- weekOverview->updateDisplay();
- }
- }
- }
-
- void
- VCal::dayViewChanged(DayView *obj, Entry *entry, Entry *oldEntry)
- {
- Pixel now, back1, arm1, top1, bot1, back2, arm2, top2, bot2;
-
- dirty = True;
- if ((!entry || !entry->repeating()) &&
- (!oldEntry || !oldEntry->repeating()) &&
- obj->month() == month && obj->year() == year) {
- count = 0;
- XtSetArg(args[count], XmNbackground, &back1); count++;
- XtSetArg(args[count], XmNarmColor, &arm1); count++;
- XtSetArg(args[count], XmNtopShadowColor, &top1); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &bot1); count++;
- XtGetValues(pref->annotateMonth() ? annotateButton : normalButton,
- args, count);
- count = 0;
- XtSetArg(args[count], XmNbackground, &back2); count++;
- XtSetArg(args[count], XmNarmColor, &arm2); count++;
- XtSetArg(args[count], XmNtopShadowColor, &top2); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &bot2); count++;
- XtGetValues(normalButton, args, count);
-
- count = 0;
- XtSetArg(args[count], XmNbackground, &now); count++;
- XtGetValues(dayWidgets[obj->day()+dayOffset-1], args, count);
- if (now != obj->info()->annotate() ? back1 : back2) {
- count = 0;
- XtSetArg(args[count], XmNbackground,
- obj->info()->annotate() ? back1 : back2); count++;
- XtSetArg(args[count], XmNarmColor,
- obj->info()->annotate() ? arm1 : arm2); count++;
- XtSetArg(args[count], XmNtopShadowColor,
- obj->info()->annotate() ? top1 : top2); count++;
- XtSetArg(args[count], XmNbottomShadowColor,
- obj->info()->annotate() ? bot1 : bot2); count++;
- XtSetValues(dayWidgets[obj->day()+dayOffset-1], args, count);
- }
- } else if ((entry && entry->repeating()) ||
- (oldEntry && oldEntry->repeating())) {
- // Many date annotations could have changed, not just today
- if (displayingCurrent) {
- displayToday();
- } else {
- setDisplayDate(0, month, year);
- }
- }
- if (dirty && pref->saveChangesAutomatically()) {
- scheduleWriteFile();
- }
- today = findDateInfo(nowDay, nowMonth, nowYear);
- if (monthOverview) {
- monthOverview->updateDisplay();
- }
- if (weekOverview) {
- weekOverview->updateDisplay();
- }
- }
-
- void
- VCal::addRepeatingEntry(RepeatingEntry *rentry)
- {
- rentry->setNext(repeatingEntries->next());
- repeatingEntries->setNext(rentry);
- numRepeats++;
- }
-
- void
- VCal::removeRepeatingEntry(RepeatingEntry *rentry)
- {
- RepeatingEntry *r;
-
- r = repeatingEntries;
- while (r->next()) {
- if (r->next() == rentry) {
- r->setNext(rentry->next());
- rentry->setNext(NULL);
- numRepeats--;
- break;
- } else {
- r = r->next();
- }
- }
- }
-
- void
- VCal::selectDay(int day, int month, int year)
- {
- if (day < 1 || day > NumberOfDays(month, year)) {
- fprintf(stderr, "Impossible, day selected is %d\n", day);
- } else {
- theApplication->busy();
-
- if (!dayView) {
- dayView = new DayView(this, "dayView");
- }
- dayView->open();
- dayView->raise();
- dayView->show();
- changeDayView(day, month, year);
- if (weekOverview) {
- weekOverview->selectWeek(day, month, year);
- }
- theApplication->notBusy();
- }
- }
-
- void
- VCal::prefChanged()
- {
- theApplication->busy();
- pref->savePreferences();
- if (dayView) {
- delete dayView;
- dayView = NULL;
- }
- if (pref->saveChangesAutomatically()) {
- writeFile();
- }
- updateDisplay(False);
- updateTheIconName(NULL);
- theApplication->notBusy();
- }
-
- void
- VCal::saveAsTextMenu(Boolean todayDefault, VkSimpleWindow *parent,
- int day, int month, int year)
- {
- Widget filesb;
-
- if (!radioText) {
- saveDay = day;
- saveMonth = month;
- saveYear = year;
- radioText = new VkPrefRadio("saveAsTextToggles", True, True);
- dayText = new VkPrefToggle("saveAsTextDay");
- weekText = new VkPrefToggle("saveAsTextWeek");
- monthText = new VkPrefToggle("saveAsTextMonth");
- if (todayDefault) {
- dayText->setValue(True);
- } else {
- monthText->setValue(True);
- }
- radioText->addItem(dayText);
- radioText->addItem(weekText);
- radioText->addItem(monthText);
- theFileSelectionDialog->setTitle("Save As Text");
- filesb =
- theFileSelectionDialog->post(NULL,
- savetext_ok,
- savetext_cancel,
- (XtPointer) this,
- (char *) VkFormat("%s.%s", className(),
- "saveAsTextDialog"),
- parent);
- radioText->build(filesb);
- radioText->show();
- }
- }
-
- MemoryInfo *
- VCal::findDateInfo(int day, int month, int year)
- {
- MemoryInfo *info;
-
- info = dayInfo;
- while (info->next()) {
- if (info->next()->sameDate(day, month, year)) {
- return info->next();
- } else {
- info = info->next();
- }
- }
- return NULL;
- }
-
- void
- VCal::getToday(int *day, int *month, int *year)
- {
- *day = nowDay;
- *month = nowMonth;
- *year = nowYear;
- }
-
- void
- VCal::displayWeekOverview()
- {
- if (dayView && dayView->visible()) {
- displayWeekOverview(dayView->day(), dayView->month(), dayView->year());
- } else {
- displayWeekOverview(nowDay, nowMonth, nowYear);
- }
- }
-
- void
- VCal::emitDay(FILE *fd, int day, int month, int year)
- {
- emitSingleDay(fd, day, month, year, True, True, "VCal: ");
- }
-
- void
- VCal::emitWeek(FILE *fd, int day, int month, int year)
- {
- int weekday, each, d, m, y;
- char str[MAXSTR];
-
- // This should be a routine in Utils
- weekday = computeWeekday(day, month, year);
- decrementDate(day, month, year, weekday-1, &d, &m, &y);
- day = d;
- month = m;
- year = y;
-
- formatDate(day, month, year, str);
- fprintf(fd, "VCal: Week of %s\n\n", str);
- for (each=0; each<DAYS_IN_WEEK; each++) {
- if (emitSingleDay(fd, day, month, year, False, False, NULL)) {
- fprintf(fd, "\n");
- }
- augmentDate(day, month, year, 1, &d, &m, &y);
- day = d;
- month = m;
- year = y;
- }
- }
-
- void
- VCal::emitMonth(FILE *fd, int, int month, int year)
- {
- int days, each;
- char str[MAXSTR];
-
- formatDate(month, year, str);
- fprintf(fd, "VCal: Month of %s\n\n", str);
- days = NumberOfDays(month, year);
- for (each=1; each<=days; each++) {
- if (emitSingleDay(fd, each, month, year, False, False, NULL)) {
- fprintf(fd, "\n");
- }
- }
- }
-
- void
- VCal::initCollect()
- {
- numCollect = 0;
- if (entries) {
- free(entries);
- entries = NULL;
- }
- }
-
- void
- VCal::collectSingleEntry(Entry *entry)
- {
- if (entries) {
- entries = (Entry **) realloc(entries, (numCollect+1)*sizeof(Entry *));
- } else {
- entries = (Entry **) malloc(sizeof(Entry *));
- }
- entries[numCollect] = entry;
- numCollect++;
- }
-
- int
- VCal::collectedCount()
- {
- return numCollect;
- }
-
- void
- VCal::sortCollection()
- {
- Entry *tmp;
- int each, each2;
-
- for (each=0; each<numCollect-1; each++) {
- for (each2=each+1; each2<numCollect; each2++) {
- if (entries[each]->start() > entries[each2]->start() ||
- (entries[each]->start() == entries[each2]->start() &&
- entries[each]->length() >
- entries[each2]->length())) {
- tmp = entries[each];
- entries[each] = entries[each2];
- entries[each2] = tmp;
- }
- }
- }
- }
-
- PrintPS *
- VCal::getPrint()
- {
- if (!print) {
- print = new PrintPS(this);
- }
- return print;
- }
-
- /**********************************************************************/
-
- void
- VCal::updateDisplay(Boolean read)
- {
- int oldDay;
- struct tm *now;
- struct timeval t;
-
- theApplication->busy();
- if (dayView) {
- oldDay = dayView->day();
- dayView->unselect();
- }
- // What was this for? It screws up the today outline if I delete a timeout
- // which is displayed right away on startup...
- // nowMonth = nowYear = nowDay = 0;
- if (read) {
- readFile();
- today = findDateInfo(nowDay, nowMonth, nowYear);
- gettimeofday(&t, NULL);
- now = localtime(&t.tv_sec);
- markTodayFired(now, False);
- }
- if (displayingCurrent) {
- displayToday();
- } else {
- setDisplayDate(0, month, year);
- }
- if (dayView && oldDay) {
- selectDay(oldDay, month, year);
- }
- intervalUpdate();
- theApplication->notBusy();
- }
-
- Widget
- VCal::setUpInterface(Widget parent)
- {
- Widget separator;
-
- pref = new Preferences(parent);
- showLates = pref->showLates();
-
- // Do this first, so that annotation of days works
- readFile();
-
- if (!pref->hideMenuBar()) {
- setMenuBar(new VkMenuBar());
- if (menu()->helpPane()) {
- menu()->helpPane()->setItemSensitivities(False, True, False, False,
- False);
- }
- fileMenu(menu());
- displayMenu(menu());
- }
- actionsPopup = new VkPopupMenu();
- actionsPopup->addLabel("vcalPopup");
- actionsPopup->addSeparator();
- fileMenu(actionsPopup);
- displayMenu(actionsPopup);
- helpMenu(actionsPopup);
- actionsPopup->build(parent);
- count = 0;
- XtSetArg(args[count], XmNpopupEnabled, False); count++;
- XtSetValues(actionsPopup->baseWidget(), args, count);
-
- count = 0;
- form = XmCreateForm(parent, "vcalForm", args, count);
- XtAddEventHandler(form, ButtonPressMask, False,
- (XtEventHandler) VCal::month_select,
- (XtPointer) this);
-
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM); count++;
- hidden = XmCreateForm(form, "hidden", args, count);
- XtManageChild(hidden);
-
- monthPrev = new VkRepeatButton("monthPrev", form, RB_arrowButtonGadget);
-
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNleftAttachment, XmATTACH_POSITION); count++;
- XtSetValues(monthPrev->baseWidget(), args, count);
- monthPrev->show();
- VkAddCallbackMethod(VkRepeatButton::buttonCallback, monthPrev, this,
- VCal::doMonthPrev, NULL);
-
- monthNext = new VkRepeatButton("monthNext", form, RB_arrowButtonGadget);
-
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNrightAttachment, XmATTACH_POSITION); count++;
- XtSetValues(monthNext->baseWidget(), args, count);
- monthNext->show();
- VkAddCallbackMethod(VkRepeatButton::buttonCallback, monthNext, this,
- VCal::doMonthNext, NULL);
-
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNleftAttachment, XmATTACH_WIDGET); count++;
- XtSetArg(args[count], XmNleftWidget, monthPrev->baseWidget()); count++;
- XtSetArg(args[count], XmNrightAttachment, XmATTACH_WIDGET); count++;
- XtSetArg(args[count], XmNrightWidget, monthNext->baseWidget()); count++;
- XtSetArg(args[count], XmNbottomAttachment,
- XmATTACH_OPPOSITE_WIDGET); count++;
- XtSetArg(args[count], XmNbottomWidget, monthPrev->baseWidget()); count++;
- monthHeader = XmCreateLabel(form, "monthHeader", args, count);
- XtManageChild(monthHeader);
- XtAddEventHandler(monthHeader, ButtonPressMask, False,
- (XtEventHandler) VCal::month_select,
- (XtPointer) this);
- count = 0;
- XtSetArg(args[count], XmNfontList, &labelFont); count++;
- XtGetValues(monthHeader, args, count);
-
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET); count++;
- XtSetArg(args[count], XmNtopWidget, monthHeader); count++;
- XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM); count++;
- XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM); count++;
- separator = XmCreateSeparatorGadget(form, "daySeparator", args, count);
- XtManageChild(separator);
-
- createDayArea(form);
- count = 0;
- XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET); count++;
- XtSetArg(args[count], XmNtopWidget, separator); count++;
- XtSetArg(args[count], XmNleftAttachment, XmATTACH_POSITION); count++;
- XtSetArg(args[count], XmNrightAttachment, XmATTACH_POSITION); count++;
- XtSetArg(args[count], XmNbottomAttachment, XmATTACH_POSITION); count++;
- XtSetValues(dayArea, args, count);
- XtAddEventHandler(dayArea, StructureNotifyMask, False,
- &VCal::resize_day,
- (XtPointer) this);
-
- count = 0;
- XtSetArg(args[count], XmNrightAttachment,
- XmATTACH_OPPOSITE_WIDGET); count++;
- XtSetArg(args[count], XmNrightWidget, dayArea); count++;
- XtSetArg(args[count], XmNbottomAttachment,
- XmATTACH_OPPOSITE_WIDGET); count++;
- XtSetArg(args[count], XmNbottomWidget, dayArea); count++;
- // This has to be a label gadget vs. label widget cuz it overlaps dayArea
- clockLabel = XmCreateLabel(form, "clockLabel", args, count);
- XtManageChild(clockLabel);
-
- count = 0;
- XtSetArg(args[count], XmNbackground, dayAreaBg); count++;
- normalButton = XmCreatePushButton(form, "normalButton", args, count);
- count = 0;
- // First try annotateColor, then sessionColor1, then sessionColor2,
- // then sessionColor3, then readOnlyBackground, then default button background
- if (VkGetResource(form, "annotateColor", "AnnotateColor")) {
- annotateBg = (Pixel) VkGetResource(form, "annotateColor",
- "AnnotateColor", XmRPixel,
- "yellow");
- } else if (VkGetResource(form, "sessionColor1", "SessionColor1")) {
- annotateBg = (Pixel) VkGetResource(form, "sessionColor1",
- "SessionColor1", XmRPixel,
- "yellow");
- } else if (VkGetResource(form, "sessionColor2", "SessionColor2")) {
- annotateBg = (Pixel) VkGetResource(form, "sessionColor2",
- "SessionColor2", XmRPixel,
- "yellow");
- } else if (VkGetResource(form, "sessionColor3", "SessionColor3")) {
- annotateBg = (Pixel) VkGetResource(form, "sessionColor3",
- "SessionColor3", XmRPixel,
- "yellow");
- } else if (VkGetResource(form, "readOnlyBackground", "ReadOnlyBackground")) {
- annotateBg = (Pixel) VkGetResource(form, "readOnlyBackground",
- "ReadOnlyBackground", XmRPixel,
- "yellow");
- } else if (VkGetResource(form, "selectColor", "SelectColor")) {
- annotateBg = (Pixel) VkGetResource(form, "selectColor",
- "SelectColor", XmRPixel,
- "red");
- } else {
- annotateBg = dayAreaBg;
- }
- if (dayAreaBg != annotateBg) {
- XtSetArg(args[count], XmNbackground, annotateBg); count++;
- }
- annotateButton = XmCreatePushButton(form, "annotateButton", args, count);
-
- XtManageChild(form);
-
- handleTimeOut();
-
- return form;
- }
-
- void
- VCal::handleWmDeleteMessage()
- {
- theApplication->quitYourself();
- }
-
- void
- VCal::fileMenu(VkMenu *parent)
- {
- VkSubMenu *menu = parent->addSubmenu("fileMenu");
-
- menu->addAction("prefMenuItem",
- VCal::pref_menu,
- (XtPointer) this);
- menu->addAction("factoryMenuItem",
- VCal::factory_menu,
- (XtPointer) this);
- menu->addSeparator();
- menu->addAction("loadMenuItem",
- VCal::load_menu,
- (XtPointer) this);
- menu->addAction("saveMenuItem",
- VCal::save_menu,
- (XtPointer) this);
- menu->addAction("saveAsMenuItem",
- VCal::saveas_menu,
- (XtPointer) this);
- menu->addAction("monthPrintMenuItem",
- VCal::month_print,
- (XtPointer) this);
- menu->addSeparator();
- menu->addAction("quitMenuItem",
- VCal::quit_menu,
- (XtPointer) this);
- }
-
- void
- VCal::displayMenu(VkMenu *parent)
- {
- VkSubMenu *menu = parent->addSubmenu("displayMenu");
-
- monthMenu(menu);
- menu->addAction("monthOverviewMenuItem",
- VCal::display_overview,
- (XtPointer) this);
- menu->addAction("weekMonthOverviewMenuItem",
- VCal::week_overview,
- (XtPointer) this);
- menu->addAction("saveAsTextMenuItem",
- VCal::save_text,
- (XtPointer) this);
- }
-
- void
- VCal::monthMenu(VkMenu *parent)
- {
- int each;
- VkCallbackStruct *callbackStructs;
- VkSubMenu *menu = parent->addSubmenu("monthMenu");
-
- callbackStructs = new VkCallbackStruct[12]; // memory leak
- for (each=0; each<12; each++) {
- callbackStructs[each].obj = this;
- callbackStructs[each].client_data = (void *) (each+1);
- menu->addAction(monthString(each+1), VCal::month_popup,
- (XtPointer) &callbackStructs[each]);
- }
-
- }
-
- void
- VCal::helpMenu(VkMenu *parent)
- {
- VkHelpPane *helpPane;
-
- helpPane = new VkHelpPane("helpMenu");
- helpPane->setItemSensitivities(False, True, False, False, False);
- parent->addSubmenu(helpPane);
- }
-
- void
- VCal::createDayArea(Widget parent)
- {
- count = 0;
- dayArea = XmCreateRowColumn(parent, "dayArea", args, count);
-
- createDayWidgets(dayArea);
-
- XtManageChild(dayArea);
- }
-
- void
- VCal::createDayWidgets(Widget parent)
- {
- int each;
- char str[16];
-
- count = 0;
- XtSetArg(args[count], XmNbackground, &dayAreaBg); count++;
- XtSetArg(args[count], XmNforeground, &dayAreaFg); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &nonHighlight); count++;
- XtGetValues(parent, args, count);
-
- count = 0;
- XtSetArg(args[count], XmNborderColor, dayAreaBg); count++;
- for (each=0; each<DAYS_IN_WEEK; each++) {
- sprintf(str, "dayHeader%d", each+1);
- // These can't be gadgets because the border width has to be consistent
- dayHeaders[each] = XmCreateLabel(parent, str, args, count);
- }
- XtManageChildren(dayHeaders, DAYS_IN_WEEK);
- for (each=0; each<MAX_DAYS; each++) {
- dayWidgets[each] = XmCreatePushButton(parent, "dayWidget", args, count);
- XtAddCallback(dayWidgets[each], XmNactivateCallback,
- VCal::day_select,
- (XtPointer) this);
- }
- XtManageChildren(dayWidgets, MAX_DAYS);
- count = 0;
- XtSetArg(args[count], XmNborderWidth, &buttonBorder); count++;
- XtGetValues(dayWidgets[0], args, count);
- }
-
- void
- VCal::setDisplayDate(int d, int m, int y)
- {
- int first;
-
- theApplication->busy();
- month = m;
- year = y;
- first = FirstDay(month, year);
- displayHeader(d, month, year);
- displayDays((first + DAYS_IN_WEEK - 1) % DAYS_IN_WEEK,
- NumberOfDays(month, year));
- annotateDays(NumberOfDays(month, year));
- if (monthOverview) {
- monthOverview->selectMonth(month, year);
- }
- theApplication->notBusy();
- }
-
- void
- VCal::displayDays(int offset, int num)
- {
- XmString xs;
- char str[8];
- int each, day;
- Dimension shadow;
- Boolean sensitive;
- Pixel back2, arm2, top2, bot2, bg;
-
- count = 0;
- XtSetArg(args[count], XmNbackground, &back2); count++;
- XtSetArg(args[count], XmNarmColor, &arm2); count++;
- XtSetArg(args[count], XmNtopShadowColor, &top2); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &bot2); count++;
- XtGetValues(normalButton, args, count);
-
- dayOffset = offset;
- for (each=0; each<MAX_DAYS; each++) {
- if (each >= dayOffset && each < dayOffset+num) {
- day = each-dayOffset+1;
- sprintf(str, "%d", day);
- xs = XmStringCreateSimple(str);
- shadow = 1;
- sensitive = True;
- bg = back2;
- } else {
- day = 0;
- xs = XmStringCreateSimple("");
- shadow = 0;
- sensitive = False;
- bg = dayAreaBg;
- }
- count = 0;
- XtSetArg(args[count], XmNuserData, day); count++;
- XtSetArg(args[count], XmNlabelString, xs); count++;
- XtSetArg(args[count], XmNshadowThickness, shadow); count++;
- XtSetArg(args[count], XmNsensitive, sensitive); count++;
- XtSetArg(args[count], XmNbackground, bg); count++;
- XtSetArg(args[count], XmNarmColor, arm2); count++;
- XtSetArg(args[count], XmNtopShadowColor, top2); count++;
- XtSetArg(args[count], XmNbottomShadowColor, bot2); count++;
- if (displayingCurrent && (each-dayOffset+1) == nowDay) {
- XtSetArg(args[count], XmNborderColor, dayAreaFg); count++;
- } else {
- XtSetArg(args[count], XmNborderColor, dayAreaBg); count++;
- }
- XtSetValues(dayWidgets[each], args, count);
- XmStringFree(xs);
- }
- }
-
- void
- VCal::displayHeader(int day, int month, int year)
- {
- char str[256];
- XmString xs;
-
- if (displayingCurrent) {
- formatDate(day, month, year, str);
- } else {
- formatDate(month, year, str);
- }
- xs = XmStringCreateSimple(str);
- count = 0;
- XtSetArg(args[count], XmNlabelString, xs); count++;
- XtSetValues(monthHeader, args, count);
- XmStringFree(xs);
- }
-
- void
- VCal::handleTimeOut()
- {
- struct timeval t;
- int excess, delay;
-
- intervalUpdate();
- gettimeofday(&t, NULL);
- excess = ((int) t.tv_sec) % pref->updateInterval();
- delay = pref->updateInterval()-excess;
- if (delay < 1) {
- delay = 1;
- }
- XtAppAddTimeOut(theApplication->appContext(), delay*1000,
- (XtTimerCallbackProc) VCal::timeout_proc,
- (XtPointer) this);
- }
-
- void
- VCal::intervalUpdate()
- {
- struct tm *now;
- struct timeval t;
-
- if (!updating) {
- updating = True;
- gettimeofday(&t, NULL);
- now = localtime(&t.tv_sec);
- updateClock(now);
- if (pref->updateIconName()) {
- updateTheIconName(now);
- } else if (pref->updateIconDate() != iconIsDate ||
- iconIsTime) {
- updateTheIconName(now);
- }
- checkDate(now);
- if (dayView) {
- dayView->updateTime();
- }
- checkAlarms(now->tm_hour*60+now->tm_min);
- checkFileStat();
- updating = False;
- }
- }
-
- void
- VCal::checkDate(struct tm *now)
- {
- if (now->tm_mday != nowDay ||
- now->tm_mon+1 != nowMonth ||
- now->tm_year+1900 != nowYear) {
- nowDay = now->tm_mday;
- nowMonth = now->tm_mon+1;
- nowYear = now->tm_year+1900;
- today = findDateInfo(nowDay, nowMonth, nowYear);
-
- if (displayingCurrent) {
- setDisplayDate(now->tm_mday, now->tm_mon+1, now->tm_year+1900);
- } else {
- setDisplayDate(now->tm_mday, month, year);
- }
-
- // Don't post alarms for those events that have already occured
- markTodayFired(now, showLates);
-
- if (pref->updateIconDate()) {
- updateTheIconName(now);
- }
- checkDayAdvanceAlarms();
- }
- showLates = False; // Only show late appointments once
- }
-
- void
- VCal::updateClock(struct tm *now)
- {
- char str[256];
- XmString xs;
-
- formatTime(now->tm_hour, now->tm_min, pref->clock24(), str);
- xs = XmStringCreateSimple(str);
- count = 0;
- XtSetArg(args[count], XmNlabelString, xs); count++;
- XtSetValues(clockLabel, args, count);
- XmStringFree(xs);
- }
-
- void
- VCal::updateTheIconName(struct tm *now)
- {
- struct timeval t;
- char str[256];
- char *name, *p;
-
- if (!now) {
- gettimeofday(&t, NULL);
- now = localtime(&t.tv_sec);
- }
- strcpy(str, "");
- iconIsTime = pref->updateIconName();
- iconIsDate = pref->updateIconDate();
- if (iconIsDate) {
- sprintf(str, "%d/%d", nowMonth, nowDay);
- if (iconIsTime) {
- strcat(str, ", ");
- } else {
- sprintf(str+strlen(str), "/%d", nowYear % 100);
- }
- }
- if (iconIsTime) {
- formatTime(now->tm_hour, now->tm_min, pref->clock24(), str+strlen(str));
- }
- if (!iconIsDate && !iconIsTime) {
- name = theApplication->argv(0);
- p = strrchr(name, '/');
- if (p) {
- p++;
- } else {
- p = name;
- }
- strcpy(str, p);
- }
- setIconName(str);
- }
-
- void
- VCal::displayToday()
- {
- struct tm *now;
- struct timeval t;
-
- displayingCurrent = True;
- gettimeofday(&t, NULL);
- now = localtime(&t.tv_sec);
- setDisplayDate(now->tm_mday, now->tm_mon+1, now->tm_year+1900);
- }
-
- void
- VCal::doMonthPrev(Widget, XtPointer, XtPointer)
- {
- if (month > 1) {
- month--;
- } else {
- month = 12;
- year--;
- }
- displayingCurrent = (month == nowMonth && year == nowYear);
- setDisplayDate(nowDay, month, year);
- }
-
- void
- VCal::doMonthNext(Widget, XtPointer, XtPointer)
- {
- if (month < 12) {
- month++;
- } else {
- month = 1;
- year++;
- }
- displayingCurrent = (month == nowMonth && year == nowYear);
- setDisplayDate(nowDay, month, year);
- }
-
- void
- VCal::daySelect(int day)
- {
- selectDay(day, month, year);
- if (day == nowDay && month == nowMonth && year == nowYear) {
- dayView->scrollToCurrentTime();
- } else {
- dayView->scrollToBeginning();
- }
- }
-
- void
- VCal::weekSelect(int day)
- {
- if (dayView) {
- changeDayView(day, month, year);
- if (day == nowDay && month == nowMonth && year == nowYear) {
- dayView->scrollToCurrentTime();
- } else {
- dayView->scrollToBeginning();
- }
- }
- displayWeekOverview(day, month, year);
- }
-
- void
- VCal::annotateDays(int num)
- {
- MemoryInfo *current;
- Pixel back1, arm1, top1, bot1;
- RepeatingEntry *rentry;
- int each;
-
- count = 0;
- XtSetArg(args[count], XmNbackground, &back1); count++;
- XtSetArg(args[count], XmNarmColor, &arm1); count++;
- XtSetArg(args[count], XmNtopShadowColor, &top1); count++;
- XtSetArg(args[count], XmNbottomShadowColor, &bot1); count++;
- XtGetValues(pref->annotateMonth() ? annotateButton : normalButton,
- args, count);
-
- count = 0;
- XtSetArg(args[count], XmNbackground, back1); count++;
- XtSetArg(args[count], XmNarmColor, arm1); count++;
- XtSetArg(args[count], XmNtopShadowColor, top1); count++;
- XtSetArg(args[count], XmNbottomShadowColor, bot1); count++;
-
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (rentry->annotate()) {
- for (each=1; each<=num; each++) {
- if (rentry->repeatApplies(each, month, year)) {
- XtSetValues(dayWidgets[each+dayOffset-1], args, count);
- }
- }
- }
- }
-
- current = dayInfo;
- while (current->next()) {
- current = current->next();
- if (current->annotate() &&
- current->month() == month && current->year() == year) {
- XtSetValues(dayWidgets[current->day()+dayOffset-1], args, count);
- }
- }
- }
-
- Boolean
- VCal::readFile()
- {
- FILE *fd;
- int each, version, numd, numr;
- char str[MAXSTR], *fname;
- MemoryInfo *current, *last;
- RepeatingEntry *rentry;
-
- fd = fopen(pref->filename(), "r");
- if (fd) {
- if (!readInt(fd, &version)) {
- sprintf(str, "%s does not have the correct file format.\nVersion number could not be read.",
- pref->filename());
- theWarningDialog->post(str);
- return False;
- // Version 5 can read version 4 files
- // alarm advance notice used to be min, now free-form text
- } else if (version > VERSION_NUMBER) {
- sprintf(str, "%s has version %d, not version %d.",
- pref->filename(), version, VERSION_NUMBER);
- theFatalErrorDialog->post(str);
- return False;
- } else if (!readInt(fd, &numd)) {
- sprintf(str, "%s does not have the correct file format.\nDay number could not be read.",
- pref->filename());
- theWarningDialog->post(str);
- return False;
- } else if (!readInt(fd, &numr)) {
- sprintf(str, "%s does not have the correct file format.\nRepeats number could not be read.",
- pref->filename());
- theWarningDialog->post(str);
- return False;
- } else {
- clearData();
- last = dayInfo;
- current = dayInfo;
- for (each=0; each<numd; each++) {
- if (!readDay(fd, current, version)) {
- sprintf(str, "%s does not have the correct file format.\nDay info was erroneous or truncated.\nThe last date read was %d/%d/%d",
- pref->filename(), last->month(), last->day(), last->year());
- theWarningDialog->post(str);
- break;
- } else {
- numDays++;
- last = current;
- current = current->next();
- }
- }
- for (each=0; each<numr; each++) {
- rentry = new RepeatingEntry();
- if (!rentry->readDate(fd, version) ||
- !rentry->readEntry(fd, version)) {
- delete rentry;
- } else {
- addRepeatingEntry(rentry);
- }
- }
- }
- fclose(fd);
- dirty = False;
- } else {
- fname = pathexpandtilde(DEFAULT_FILENAME);
- if (strcmp(pref->filename(), fname)) {
- sprintf(str, "Couldn't read %s.", pref->filename());
- theWarningDialog->post(str);
- }
- return False;
- }
- updateFileStat();
- return True;
- }
-
- Boolean
- VCal::readDay(FILE *fd, MemoryInfo *parent, int version)
- {
- MemoryInfo *info;
-
- info = new MemoryInfo();
- if (info->readDay(fd, version)) {
- parent->setNext(info);
- return True;
- } else {
- delete info;
- return False;
- }
- }
-
- void
- VCal::scheduleWriteFile()
- {
- if (!writeID) {
- writeID = XtAppAddWorkProc(XtWidgetToApplicationContext(_baseWidget),
- VCal::write_file,
- (XtPointer) this);
- }
- }
-
- Boolean
- VCal::writeFile()
- {
- FILE *fd;
- char str[256], tempFile[256], *dir;
- int each, adjust;
- MemoryInfo *current;
- RepeatingEntry *rentry;
-
- if (fileChanged()) {
- if (checkInhibited) {
- return False;
- }
- inhibitCheckFile();
- if (theQuestionDialog->postAndWait(
- "Someone else has changed the database file.\nOverwrite their changes?")
- == VkDialogManager::CANCEL) {
- allowCheckFile();
- checkFileSoon();
- return False;
- }
- allowCheckFile();
- }
-
- dir = pathdirname(pref->filename());
- if (dir && strlen(dir)) {
- sprintf(tempFile, "%s/.vcal-XXXXXX", dir);
- } else {
- strcpy(tempFile, ".vcal-XXXXXX");
- }
- mktemp(tempFile);
- fd = fopen(tempFile, "w");
- /* Don't do this, since it will clobber the .vcal file if the filesystem
- is full, there are too many open files, etc.
- if (!fd) {
- strcpy(tempFile, pref->filename());
- fd = fopen(tempFile, "w");
- }
- */
- if (!fd) {
- sprintf(str, "Couldn't create or write %s.", pref->filename());
- theWarningDialog->post(str);
- return False;
- } else {
- writeInt(fd, VERSION_NUMBER,
- pref->annotateFile() ? "Version Number" : NULL);
- adjust = 0;
- current = dayInfo;
- for (each=0; each<numDays; each++) {
- current = current->next();
- if (!current->size()) {
- adjust++;
- }
- }
- writeInt(fd, numDays-adjust,
- pref->annotateFile() ? "Number of Days" : NULL);
- writeInt(fd, numRepeats,
- pref->annotateFile() ? "Number of Repeating Entries" : NULL);
- current = dayInfo;
- for (each=0; each<numDays; each++) {
- current = current->next();
- if (current->size()) {
- current->writeDay(fd, pref->annotateFile());
- }
- }
- rentry = repeatingEntries;
- for (each=0; each<numRepeats; each++) {
- rentry = rentry->next();
- rentry->writeDate(fd, pref->annotateFile());
- rentry->writeEntry(fd, pref->annotateFile());
- }
- fclose(fd);
- dirty = False;
- if (strcmp(tempFile, pref->filename())) {
- // First, preserve the mode of the file
- updateFileStat();
- if (lastFileStat.st_mtime) {
- chmod(tempFile, lastFileStat.st_mode);
- }
- rename(tempFile, pref->filename());
- }
- updateFileStat();
- return True;
- }
- }
-
- void
- VCal::loadMenu()
- {
- char *oldFile;
-
- theFileSelectionDialog->setTitle("Load Database");
- theFileSelectionDialog->setSelection(pref->filename());
- theFileSelectionDialog->postAndWait(NULL, VkFormat("%s.%s", className(), "loadDialog"), this);
-
- if (theFileSelectionDialog->fileName())
- {
- oldFile = strdup(pref->filename());
- pref->setFilename(theFileSelectionDialog->fileName());
- if (!readFile()) {
- // If the load fails, don't change the filename for the next save
- pref->setFilename(oldFile);
- }
- updateDisplay(True);
- free(oldFile);
- }
- }
-
- void
- VCal::saveAsMenu()
- {
- theFileSelectionDialog->setTitle("Save Database");
- theFileSelectionDialog->setSelection(pref->filename());
- theFileSelectionDialog->postAndWait(NULL, VkFormat("%s.%s", className(), "saveDialog"), this);
-
- if (theFileSelectionDialog->fileName())
- {
- pref->setFilename(theFileSelectionDialog->fileName());
- writeFile();
- pref->savePreferences();
- }
- }
-
- void
- VCal::saveAsTextOK()
- {
- FILE *fd;
- char str[MAXSTR];
-
- if (theFileSelectionDialog->fileName()) {
- if (fd = fopen(theFileSelectionDialog->fileName(), "w")) {
- if (dayText->getValue()) {
- emitDay(fd, saveDay, saveMonth, saveYear);
- } else if (weekText->getValue()) {
- emitWeek(fd, saveDay, saveMonth, saveYear);
- } else if (monthText->getValue()) {
- emitMonth(fd, saveDay, saveMonth, saveYear);
- }
- fclose(fd);
- } else {
- sprintf(str, "Couldn't write to %s", theFileSelectionDialog->fileName());
- theWarningDialog->post(str);
- }
- }
- }
-
- void
- VCal::saveAsTextCancel()
- {
- radioText->deleteChildren();
- delete radioText;
- radioText = NULL;
- dayText = weekText = monthText = NULL;
- }
-
- void
- VCal::displayMonthOverview()
- {
- theApplication->busy();
- if (!monthOverview) {
- monthOverview = new MonthOverview(this, "monthOverview");
- }
- monthOverview->selectMonth(nowMonth, nowYear);
- monthOverview->open();
- monthOverview->raise();
- monthOverview->show();
- theApplication->notBusy();
- }
-
- void
- VCal::displayWeekOverview(int day, int month, int year)
- {
- theApplication->busy();
- if (!weekOverview) {
- weekOverview = new WeekOverview(this, "weekOverview");
- // Gotta build the grid right away...
- weekOverview->show();
- }
- weekOverview->selectWeek(day, month, year);
- weekOverview->open();
- weekOverview->raise();
- weekOverview->show();
- theApplication->notBusy();
- }
-
- void
- VCal::monthPrint()
- {
- theApplication->busy();
- getPrint()->printMonthUI(month, year);
- theApplication->notBusy();
- }
-
- void
- VCal::prefMenu()
- {
- if (!prefDialog) {
- prefDialog = new PrefDialog(this, pref, "prefDialog");
- } else {
- prefDialog->updateDisplay();
- }
- prefDialog->post(NULL, NULL, NULL, NULL, NULL, "prefDialog");
- if (prefDialog->baseWidget() &&
- XtWindow(prefDialog->baseWidget())) {
- XRaiseWindow(XtDisplay(prefDialog->baseWidget()),
- XtWindow(prefDialog->baseWidget()));
- }
- }
-
- void
- VCal::factoryMenu()
- {
- if (theQuestionDialog->postAndWait("Are you sure that you want to revert your preferences settings?")) {
- theApplication->busy();
- pref->useFactory();
- if (prefDialog) {
- prefDialog->updateDisplay();
- }
- prefChanged();
- theApplication->notBusy();
- }
- }
-
- void
- VCal::checkAlarms(int t)
- {
- Entry *entry;
- RepeatingEntry *rentry;
- int alarmIndex;
-
- if (today) {
- today->rewind();
- while (entry = today->nextEntry()) {
- if (entry->alarmApplies(t, &alarmIndex) &&
- !entry->alarmFired(alarmIndex)) {
- handleEntryAlarm(entry, nowDay, nowMonth, nowYear);
- entry->setAlarmFired(1, alarmIndex);
- }
- }
- }
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (rentry->alarmApplies(t, &alarmIndex) &&
- !rentry->alarmFired(alarmIndex) &&
- rentry->repeatApplies(nowDay, nowMonth, nowYear)) {
- handleEntryAlarm(rentry, nowDay, nowMonth, nowYear);
- rentry->setAlarmFired(1, alarmIndex);
- }
- }
- }
-
- void
- VCal::checkDayAdvanceAlarms()
- {
- MemoryInfo *info;
- Entry *entry;
- RepeatingEntry *rentry;
- int alarmIndex;
- int matchDay, matchMonth, matchYear;
-
- info = dayInfo;
- while (info->next()) {
- info = info->next();
- info->rewind();
- while (entry = info->nextEntry()) {
- if (entry->alarmApplies(nowDay, nowMonth, nowYear, &alarmIndex,
- &matchDay, &matchMonth, &matchYear)) {
- handleEntryAlarm(entry, matchDay, matchMonth, matchYear);
- entry->setAlarmFired(1, alarmIndex);
- }
- }
- }
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (rentry->alarmApplies(nowDay, nowMonth, nowYear, &alarmIndex,
- &matchDay, &matchMonth, &matchYear)) {
- // Hmm. How do we get the real date information?
- handleEntryAlarm(rentry, matchDay, matchMonth, matchYear);
- rentry->setAlarmFired(1, alarmIndex);
- }
- }
- }
-
- void
- VCal::postAlarm(Entry *entry, int day, int month, int year, Boolean late)
- {
- char *str, dstr[256], tstr[256];
- int ddiff;
- VkQuestionDialog *dialog;
- EntryAlarmInfo *info;
-
- XForceScreenSaver(XtDisplay(_baseWidget), ScreenSaverReset);
- info = entry->alarmInfo();
- dialog = (VkQuestionDialog *) info->alarm;
- if (dialog) {
- dialog->hide();
- } else {
- if (entry->repeating()) {
- dialog = new VkQuestionDialog("repeatAlarmDialog");
- } else {
- dialog = new VkQuestionDialog("alarmDialog");
- }
- info->alarm = (void *) dialog;
- info->data = (void *) this;
- dialog->centerOnScreen(TRUE);
- }
- ddiff = computeDayDifference(day, month, year, nowDay, nowMonth, nowYear);
- if (!ddiff) {
- strcpy(dstr, "");
- } else if (ddiff == 1) {
- strcpy(dstr, "Tomorrow, ");
- } else {
- formatDate(day, month, year, dstr);
- strcat(dstr, ", ");
- }
- formatTime(entry->start() / 60, entry->start() % 60, pref->clock24(), tstr);
- str = (char *) malloc(strlen(entry->text())+256);
- if (late) {
- sprintf(str, "VCal (missed): %s%s\n\n%s", dstr, tstr, entry->text());
- } else {
- sprintf(str, "VCal: %s%s\n\n%s", dstr, tstr, entry->text());
- }
- dialog->post(str,
- VCal::alarm_dismiss,
- VCal::alarm_delete,
- VCal::alarm_snooze,
- (XtPointer) info);
- free(str);
- }
-
- void
- VCal::clearData()
- {
- // Memory leak -- delete lists
- delete repeatingEntries;
- delete dayInfo;
-
- dayInfo = new MemoryInfo();
- repeatingEntries = new RepeatingEntry();
- numDays = 0;
- numRepeats = 0;
- }
-
- void
- VCal::selectMonth(int month)
- {
- displayingCurrent = (month == nowMonth && year == nowYear);
- setDisplayDate(nowDay, month, year);
- }
-
- Boolean VCal::okToQuit()
- {
- if (dirty)
- {
- VkDialogManager::VkDialogReason result;
-
- result = theQuestionDialog->postAndWait("There are unsaved changes. Save before quitting?",
- TRUE, TRUE, TRUE,
- "saveBeforeQuit",
- this);
- if(result == VkDialogManager::OK)
- {
- writeFile();
- return TRUE;
- }
- else if(result == VkDialogManager::CANCEL)
- {
- return FALSE;
- }
- }
- return TRUE;
- }
-
-
- void
- VCal::resizeDay()
- {
- Dimension width, height, marginW, marginH, spacing, bWidth, bHeight, n;
- short numColumns;
- int each;
-
- count = 0;
- XtSetArg(args[count], XmNwidth, &width); count++;
- XtSetArg(args[count], XmNheight, &height); count++;
- XtSetArg(args[count], XmNmarginWidth, &marginW); count++;
- XtSetArg(args[count], XmNmarginHeight, &marginH); count++;
- XtSetArg(args[count], XmNspacing, &spacing); count++;
- XtSetArg(args[count], XmNnumColumns, &numColumns); count++;
- XtGetValues(dayArea, args, count);
- count = 0;
- XtSetArg(args[count], XmNwidth, &bWidth); count++;
- XtSetArg(args[count], XmNheight, &bHeight); count++;
- XtGetValues(dayWidgets[0], args, count);
- count = 0;
- if (width >= 2*marginW+(DAYS_IN_WEEK-1)*spacing) {
- n = (width-2*marginW-(DAYS_IN_WEEK-1)*spacing)/DAYS_IN_WEEK-2*buttonBorder;
- if (n != bWidth) {
- XtSetArg(args[count], XmNwidth, n); count++;
- }
- }
- if (height >= 2*marginH+(numColumns-1)*spacing) {
- n = (height-2*marginH-(numColumns-1)*spacing)/numColumns-2*buttonBorder;
- if (n != bHeight) {
- XtSetArg(args[count], XmNheight, n); count++;
- }
- }
- if (count) {
- // If I don't do this, resizing the children has no effect
- XtUnmanageChild(dayArea);
- // If I don't do this, the buttons can't get smaller
- XtUnmanageChildren(dayHeaders, DAYS_IN_WEEK);
- XtUnmanageChildren(dayWidgets, MAX_DAYS);
- for (each=0; each<DAYS_IN_WEEK; each++) {
- XtSetValues(dayHeaders[each], args, count);
- }
- for (each=0; each<MAX_DAYS; each++) {
- XtSetValues(dayWidgets[each], args, count);
- }
- XtManageChildren(dayHeaders, DAYS_IN_WEEK);
- XtManageChildren(dayWidgets, MAX_DAYS);
- XtManageChild(dayArea);
- }
- if (hidden) {
- XtDestroyWidget(hidden);
- hidden = NULL;
- }
- }
-
- void
- VCal::displayActionsPopup(XButtonPressedEvent *event)
- {
- XmMenuPosition(actionsPopup->baseWidget(), event);
- XtManageChild(actionsPopup->baseWidget());
- }
-
- void
- VCal::updateFileStat()
- {
- if (stat(pref->filename(), &lastFileStat) == -1) {
- lastFileStat.st_mtime = 0;
- }
- }
-
- void
- VCal::checkFileStat()
- {
- if (!checkInhibited) {
- if (fileChanged()) {
- if (!dirty) {
- updateDisplay(True);
- } else {
- inhibitCheckFile();
- if (theQuestionDialog->postAndWait(
- "Someone else has changed the database file and you have unsaved changes.\nThrow away your changes?")) {
- updateDisplay(True);
- } else {
- // The next time we write, user will be asked to overwrite the other changes
- }
- allowCheckFile();
- }
- }
- }
- }
-
- Boolean
- VCal::fileChanged()
- {
- struct stat currentFileStat;
-
- if (stat(pref->filename(), ¤tFileStat) == -1) {
- return False;
- } else {
- return (!currentFileStat.st_mtime ||
- currentFileStat.st_mtime != lastFileStat.st_mtime);
- }
- }
-
- void
- VCal::checkFileSoon()
- {
- XtAppAddWorkProc(theApplication->appContext(),
- VCal::check_file, (XtPointer) this);
- }
-
- void
- VCal::markTodayFired(struct tm *now, Boolean lates)
- {
- Entry *entry;
- RepeatingEntry *rentry;
-
- if (today) {
- today->rewind();
- while (entry = today->nextEntry()) {
- if (entry->start() < now->tm_hour*60+now->tm_min) {
- if (lates) {
- handleEntryAlarm(entry, nowDay, nowMonth, nowYear, True);
- }
- entry->setAlarmFired(1, ALL_NOTIFICATIONS);
- } else {
- entry->setAlarmFired(0, ALL_NOTIFICATIONS);
- }
- }
- }
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (rentry->start() < now->tm_hour*60+now->tm_min &&
- rentry->repeatApplies(nowDay, nowMonth, nowYear)) {
- if (lates) {
- handleEntryAlarm(rentry, nowDay, nowMonth, nowYear, True);
- }
- rentry->setAlarmFired(1, ALL_NOTIFICATIONS);
- } else {
- rentry->setAlarmFired(0, ALL_NOTIFICATIONS);
- }
- }
- }
-
- void
- VCal::snoozeAlarm(Entry *entry)
- {
- XtIntervalId id;
-
- id = XtAppAddTimeOut(theApplication->appContext(),
- pref->snoozeMinutes()*60*1000,
- (XtTimerCallbackProc) VCal::snooze_proc,
- (XtPointer) this);
- entry->setSnoozeData((void *) id);
- }
-
- void
- VCal::handleSnooze(XtIntervalId id)
- {
- Entry *entry;
- RepeatingEntry *rentry;
- int oldDay, oldMonth, oldYear;
-
- if (today) {
- today->rewind();
- while (entry = today->nextEntry()) {
- if (((XtIntervalId) entry->snoozeData()) == id) {
- entry->setSnoozeData(NULL);
- handleEntryAlarm(entry, nowDay, nowMonth, nowYear, False);
- }
- }
- }
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (((XtIntervalId) rentry->snoozeData()) == id) {
- rentry->setSnoozeData(NULL);
- // Actual repeat match information is no longer available
- handleEntryAlarm(rentry, nowDay, nowMonth, nowYear, False);
- }
- }
-
- // Oh well, I guess we past Midnight while we snoozed, go back to yesterday
-
- if (nowDay > 1) {
- oldDay = nowDay-1;
- oldMonth = nowMonth;
- oldYear = nowYear;
- } else if (nowMonth > 1) {
- oldDay = NumberOfDays(nowMonth-1, nowYear);
- oldMonth = nowMonth-1;
- oldYear = nowYear;
- } else {
- oldDay = NumberOfDays(12, nowYear);
- oldMonth = 12;
- oldYear = nowYear-1;
- }
- today = findDateInfo(oldDay, oldMonth, oldYear);
- if (today) {
- today->rewind();
- while (entry = today->nextEntry()) {
- if (((XtIntervalId) entry->snoozeData()) == id) {
- entry->setSnoozeData(NULL);
- handleEntryAlarm(entry, oldDay, oldMonth, oldYear, False);
- }
- }
- }
- today = findDateInfo(nowDay, nowMonth, nowYear);
- }
-
- void
- VCal::alarmDismiss(EntryAlarmInfo *info)
- {
- VkQuestionDialog *dialog;
-
- if (dialog = (VkQuestionDialog *) info->alarm) {
- scheduleDialogDelete(dialog);
- info->alarm = NULL;
- }
- }
-
- void
- VCal::alarmDelete(EntryAlarmInfo *info)
- {
- Boolean worked = False;
-
- alarmDismiss(info);
- if (!pref->notifyConfirmDelete() ||
- theQuestionDialog->postAndWait("Are you sure that you want to delete the entry that caused this alarm?")) {
- if (dayView) {
- if (dayView->eraseEntry(info->entry)) {
- worked = True;
- }
- }
- if (info->entry->repeating()) {
- removeRepeatingEntry((RepeatingEntry *) info->entry);
- worked = True;
- } else if (today && today->removeEntry(info->entry)) {
- worked = True;
- }
- if (worked) {
- if (pref->saveChangesAutomatically()) {
- writeFile();
- }
- updateDisplay(False);
- } else {
- theWarningDialog->post("That entry could not be deleted. To delete entries from other days,\nuse the DayView and access the entry directly.");
- }
- }
- }
-
- void
- VCal::alarmSnooze(EntryAlarmInfo *info)
- {
- alarmDismiss(info);
-
- snoozeAlarm(info->entry);
- }
-
- void
- VCal::scheduleDialogDelete(VkQuestionDialog *dialog)
- {
- XtAppAddWorkProc(theApplication->appContext(),
- VCal::dialog_delete, (XtPointer) dialog);
- }
-
- void
- VCal::handleEntryAlarm(Entry *entry, int day, int month, int year,
- Boolean late)
- {
- if (pref->alarms()) {
- if (entry->notifyMail()) {
- sendMailNotification(entry, day, month, year, late);
- }
- if (strlen(entry->notifyCommand())) {
- VkExecCommand(entry->notifyCommand());
- }
- if (entry->notifyPopup()) {
- postAlarm(entry, day, month, year, late);
- }
- if (entry->notifyBell()) {
- XBell(theApplication->display(), 0);
- }
- }
- }
-
- void
- VCal::sendMailNotification(Entry *entry, int day, int month, int year,
- Boolean late)
- {
- char str[MAXSTR], tempFile[256], dstr[256], tstr[256];
- int ddiff;
- struct passwd *passwd;
- FILE *fd;
-
- if (getenv("TMPDIR")) {
- sprintf(tempFile, "%s/.vcal-XXXXXX", getenv("TMPDIR"));
- } else {
- sprintf(tempFile, "/tmp/.vcal-XXXXXX");
- }
- mktemp(tempFile);
- if (fd = fopen(tempFile, "w")) {
- ddiff = computeDayDifference(day, month, year, nowDay, nowMonth, nowYear);
- if (!ddiff) {
- strcpy(dstr, "");
- } else if (ddiff == 1) {
- strcpy(dstr, "Tomorrow, ");
- } else {
- formatDate(day, month, year, dstr);
- strcat(dstr, ", ");
- }
- formatTime(entry->start() / 60, entry->start() % 60, pref->clock24(),
- tstr);
- if (late) {
- fprintf(fd, "VCal (missed): %s%s\n\n", dstr, tstr);
- } else {
- fprintf(fd, "VCal: %s%s\n\n", dstr, tstr);
- }
- fputs(entry->text(), fd);
- fclose(fd);
- if (passwd = getpwuid(getuid())) {
- sprintf(str, "/usr/sbin/Mail -s 'VCal-Notification' %s < %s",
- passwd->pw_name, tempFile);
- system(str);
- }
- unlink(tempFile);
- }
- }
-
- Boolean
- VCal::emitSingleDay(FILE *fd, int day, int month, int year,
- Boolean headerAlways, Boolean formatYear, char *prefix)
- {
- MemoryInfo *dayInfo;
- char str[MAXSTR];
- Entry *entry;
- RepeatingEntry *rentry;
- int weekday;
-
- dayInfo = findDateInfo(day, month, year);
- initCollect();
- if (dayInfo) {
- dayInfo->rewind();
- while (entry = dayInfo->nextEntry()) {
- collectSingleEntry(entry);
- }
- }
- rentry = repeatingEntries;
- while (rentry->next()) {
- rentry = rentry->next();
- if (rentry->repeatApplies(day, month, year)) {
- collectSingleEntry(rentry);
- }
- }
- if (collectedCount() || headerAlways) {
- weekday = computeWeekday(day, month, year);
- formatDate(weekday, day, month, formatYear ? year : 0, str);
- if (prefix) {
- fputs(prefix, fd);
- }
- fprintf(fd, "%s\n\n", str);
- emitCollectedEntries(fd);
- }
- return (collectedCount() > 0);
- }
-
- void
- VCal::emitCollectedEntries(FILE *fd)
- {
- int each;
-
- if (numCollect) {
- sortCollection();
- for (each=0; each<numCollect; each++) {
- entries[each]->printEntry(fd, pref->clock24());
- }
- }
- }
-
- void
- VCal::changeDayView(int day, int month, int year)
- {
- MemoryInfo *info;
-
- info = dayInfo;
- while (info->next() &&
- !info->next()->sameDate(day, month, year)) {
- info = info->next();
- }
- if (!info->next()) {
- numDays++;
- info->setNext(new MemoryInfo());
- info->next()->setDate(day, month, year);
- }
- info = info->next();
- dayView->selectDate(day, month, year, info, repeatingEntries);
- }
-
- /**********************************************************************/
-
- VCal::VCal(const char *docName): VkWindow(docName)
- {
- monthHeader = NULL;
- month = year = nowMonth = nowYear = nowDay = 0;
- displayingCurrent = True;
- dayView = NULL;
- dayInfo = new MemoryInfo();
- numDays = 0;
- numRepeats = 0;
- dirty = False;
- today = NULL;
- repeatingEntries = new RepeatingEntry();
- monthPrev = NULL;
- actionsPopup = NULL;
- lastFileStat.st_mtime = 0;
- checkInhibited = False;
- hidden = NULL;
- updating = False;
- pref = NULL;
- prefDialog = NULL;
- iconIsTime = False;
- iconIsDate = False;
- radioText = NULL;
- dayText = weekText = monthText = NULL;
- entries = NULL;
- monthOverview = NULL;
- weekOverview = NULL;
- tile = NULL;
- print = NULL;
- writeID = NULL;
-
- VkInitializeChildrenHandler();
- }
-
- VCal::~VCal()
- {
- if (actionsPopup) {
- delete actionsPopup;
- }
- if (monthPrev) {
- delete monthPrev;
- delete monthNext;
- }
- if (pref) {
- delete pref;
- }
- if (prefDialog) {
- delete prefDialog;
- }
- if (print) {
- delete print;
- }
- if (monthHeader) {
- XtRemoveEventHandler(monthHeader, ButtonPressMask, False,
- (XtEventHandler) VCal::month_select,
- (XtPointer) this);
- XtRemoveEventHandler(dayArea, StructureNotifyMask, False,
- (XtEventHandler) VCal::resize_day,
- (XtPointer) this);
- }
- if (entries) {
- free(entries);
- }
- if (tile) {
- XFreePixmap(XtDisplay(_baseWidget), tile);
- }
-
- if (dayView) {
- // delete dayView; Can\'t delete this, it's already been done by theApplication
- }
- if (monthOverview) {
- // delete monthOverview; Can\'t delete this, it's already been done by theApplication
- }
- if (weekOverview) {
- // delete weekOverview; Can\'t delete this, it's already been done by theApplication
- }
-
- clearData();
- }
-
- const char *
- VCal::className()
- {
- return "VCal";
- }
-